package com.rickpan.storage.task;

import com.rickpan.storage.health.StorageHealthService;
import com.rickpan.storage.monitor.StorageMetricsService;
import com.rickpan.storage.performance.StoragePerformanceAnalyzer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 存储监控定时任务
 * 定期执行存储系统的监控和分析任务
 */
@Component
public class StorageMonitoringTask {
    
    private static final Logger logger = LoggerFactory.getLogger(StorageMonitoringTask.class);
    
    @Autowired
    private StorageHealthService healthService;
    
    @Autowired
    private StorageMetricsService metricsService;
    
    @Autowired
    private StoragePerformanceAnalyzer performanceAnalyzer;
    
    /**
     * 每5分钟检查存储健康状态
     */
    @Scheduled(fixedRate = 5 * 60 * 1000) // 5分钟
    public void checkStorageHealth() {
        try {
            logger.debug("开始定时存储健康检查");
            
            StorageHealthService.HealthStatus health = healthService.health();
            String status = health.getStatus();
            
            if ("UP".equals(status)) {
                logger.debug("存储健康检查正常: {}", status);
            } else {
                logger.warn("存储健康检查异常: {}, 详情: {}", status, health.getDetails());
                
                // 这里可以添加告警逻辑
                sendHealthAlert(health);
            }
            
        } catch (Exception e) {
            logger.error("定时存储健康检查失败", e);
        }
    }
    
    /**
     * 每30分钟记录存储统计信息（减少日志频率）
     */
    @Scheduled(fixedRate = 30 * 60 * 1000) // 30分钟
    public void logStorageStats() {
        try {
            // logger.debug("开始记录存储统计信息"); // 开发调试用

            StorageMetricsService.StorageStats stats = metricsService.getStorageStats();

            // 只有在有实际操作时才记录日志
            if (stats.getTotalOperations() > 0) {
                logger.info("存储统计信息 - 总操作数: {}, 活跃操作: {}, 上传字节: {}, 下载字节: {}",
                           stats.getTotalOperations(),
                           stats.getActiveOperations(),
                           formatBytes(stats.getTotalUploadedBytes()),
                           formatBytes(stats.getTotalDownloadedBytes()));
            }

            // 检查异常情况
            if (stats.getActiveOperations() > 100) {
                logger.warn("活跃操作数量过高: {}", stats.getActiveOperations());
            }

        } catch (Exception e) {
            logger.error("记录存储统计信息失败", e);
        }
    }
    
    /**
     * 每60分钟执行性能分析（减少频率）
     */
    @Scheduled(fixedRate = 60 * 60 * 1000) // 60分钟
    public void performanceAnalysis() {
        try {
            // logger.debug("开始定时性能分析"); // 开发调试用

            StoragePerformanceAnalyzer.PerformanceReport report = performanceAnalyzer.generatePerformanceReport();

            if (report.getIssues().isEmpty()) {
                logger.info("性能分析完成 - 未发现问题");
            } else {
                logger.warn("性能分析发现 {} 个问题:", report.getIssues().size());
                
                // 记录关键问题
                for (StoragePerformanceAnalyzer.PerformanceIssue issue : report.getIssues()) {
                    if (issue.getSeverity() == StoragePerformanceAnalyzer.PerformanceIssue.Severity.CRITICAL ||
                        issue.getSeverity() == StoragePerformanceAnalyzer.PerformanceIssue.Severity.ERROR) {
                        logger.error("🚨 严重性能问题: {} - {}", issue.getTitle(), issue.getDescription());
                    } else {
                        logger.warn("⚠️ 性能问题: {} - {}", issue.getTitle(), issue.getDescription());
                    }
                }
                
                // 记录优化建议
                if (!report.getRecommendations().isEmpty()) {
                    logger.info("💡 优化建议:");
                    for (StoragePerformanceAnalyzer.OptimizationRecommendation rec : report.getRecommendations()) {
                        logger.info("  - {}: {}", rec.getTitle(), rec.getDescription());
                    }
                }
                
                // 发送性能告警
                sendPerformanceAlert(report);
            }
            
        } catch (Exception e) {
            logger.error("定时性能分析失败", e);
        }
    }
    
    /**
     * 每小时清理过期的监控数据
     */
    @Scheduled(fixedRate = 60 * 60 * 1000) // 1小时
    public void cleanupMonitoringData() {
        try {
            logger.debug("开始清理过期监控数据");
            
            // 这里可以添加清理逻辑，比如：
            // - 清理过期的性能报告
            // - 清理过期的健康检查记录
            // - 清理过期的指标数据
            
            logger.debug("监控数据清理完成");
            
        } catch (Exception e) {
            logger.error("清理监控数据失败", e);
        }
    }
    
    /**
     * 每天凌晨生成日报
     */
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点
    public void generateDailyReport() {
        try {
            logger.info("开始生成存储系统日报");
            
            // 获取健康状态
            StorageHealthService.HealthStatus health = healthService.health();
            
            // 获取统计信息
            StorageMetricsService.StorageStats stats = metricsService.getStorageStats();
            
            // 获取性能报告
            StoragePerformanceAnalyzer.PerformanceReport perfReport = performanceAnalyzer.generatePerformanceReport();
            
            // 生成日报
            StringBuilder report = new StringBuilder();
            report.append("\n").append("=".repeat(60)).append("\n");
            report.append("📊 RickPan 存储系统日报\n");
            report.append("=".repeat(60)).append("\n");
            report.append("📅 日期: ").append(java.time.LocalDate.now()).append("\n");
            report.append("🏥 健康状态: ").append(health.getStatus()).append("\n");
            report.append("📈 总操作数: ").append(stats.getTotalOperations()).append("\n");
            report.append("📤 总上传量: ").append(formatBytes(stats.getTotalUploadedBytes())).append("\n");
            report.append("📥 总下载量: ").append(formatBytes(stats.getTotalDownloadedBytes())).append("\n");
            report.append("⚡ 活跃操作: ").append(stats.getActiveOperations()).append("\n");
            
            if (!perfReport.getIssues().isEmpty()) {
                report.append("⚠️ 性能问题: ").append(perfReport.getIssues().size()).append(" 个\n");
                for (StoragePerformanceAnalyzer.PerformanceIssue issue : perfReport.getIssues()) {
                    report.append("  - ").append(issue.getTitle()).append("\n");
                }
            } else {
                report.append("✅ 性能状态: 良好\n");
            }
            
            if (!perfReport.getRecommendations().isEmpty()) {
                report.append("💡 优化建议: ").append(perfReport.getRecommendations().size()).append(" 条\n");
                for (StoragePerformanceAnalyzer.OptimizationRecommendation rec : perfReport.getRecommendations()) {
                    report.append("  - ").append(rec.getTitle()).append("\n");
                }
            }
            
            report.append("=".repeat(60)).append("\n");
            
            logger.info(report.toString());
            
            // 这里可以添加发送邮件或其他通知方式
            
        } catch (Exception e) {
            logger.error("生成存储系统日报失败", e);
        }
    }
    
    /**
     * 发送健康告警
     */
    private void sendHealthAlert(StorageHealthService.HealthStatus health) {
        // 这里可以实现具体的告警逻辑，比如：
        // - 发送邮件
        // - 发送短信
        // - 推送到监控系统
        // - 写入告警日志

        logger.error("🚨 存储健康告警: 状态={}, 详情={}", health.getStatus(), health.getDetails());
    }
    
    /**
     * 发送性能告警
     */
    private void sendPerformanceAlert(StoragePerformanceAnalyzer.PerformanceReport report) {
        // 检查是否有严重问题需要立即告警
        long criticalIssues = report.getIssues().stream()
            .filter(issue -> issue.getSeverity() == StoragePerformanceAnalyzer.PerformanceIssue.Severity.CRITICAL)
            .count();
        
        if (criticalIssues > 0) {
            logger.error("🚨 存储性能严重告警: {} 个严重问题", criticalIssues);
            
            // 这里可以实现紧急告警逻辑
        }
    }
    
    /**
     * 格式化字节数
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
        if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
        return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
    }
}
